<?php if(!defined('CALL')) exit('No direct script access allowed');

include_once('lib/mysql.class.php');
include_once('lib/utils.class.php');
include_once('cfg/cfg.php');

class Parser
{
	private $db = null;
	private $companies = null;
	private $logs = null;
	
	public function __construct()
	{
		global $dburl, $def_encoding;
		MySQL::$url = $dburl;
		MySQL::$encoding = $def_encoding;
		$this->db = MySQL::getInstance();
		$this->logs = array();
	}
	
	public function load_data()
	{
		$this->companies = $this->load_companies();
	}
	
	public function get_messages()
	{
		$a = array_merge($this->logs);
		array_splice($this->logs, 0);
		return $a;
	}
	
	/*
	public function get_company_props($letter)
	{
		$this->save_msg($letter);
		$this->load_companies();
		
		$email = $this->get_letter_sour_addr($letter);
		foreach($this->companies as $comp)
		{
			if(array_search($email, $comp['emails']) !== false)
			{
				$this->save_company($comp["id"]);
				$this->logs[] = "COMPANY title:[".$comp["title"]."] email [".$email."] from [".$comp["info"]."]";
				return $comp;
			}
		}
		return false;
	}
	
	// ищем идентификатор клиента в письме
	public function get_identificators($letter, $comp)
	{
		$id_list = array();

		$re_list = $this->load_re_list($comp, "id");
		foreach($re_list as $re)
			if(preg_match("/".$re["re_find"]."/", $letter, $matches))
			{
				$re["match"] = $matches[1];
				$id_list[] = $re;
				$msg = "match:[".$this->db->escape(($matches[0]))."]";
				$this->logs[] = "USERID title:[".$re["title"]."] $msg";
				$this->save_re($re['id'], $re["match"]);
			}
		
		$this->logs[] = "FOUND identificators:[".count($id_list)."]";
		return $id_list;
	}
	
	public function get_clients($id_list, $comp)
	{
		$cli_list = array();
		
		$clients = $this->load_clients($comp);
		foreach($clients as $cli)
		{
			foreach($id_list as $id)
			{
				// print_r($id);
				if(($cli["ident"] == $id["match"]) && ($cli["enabled"] == 1))
				{
					$cli_list[] = $cli;
					$msg = "title:[".$cli["title"]."] id:[".$cli["ident"]."]";
					$this->logs[] = "CLIENT $msg";
					$this->save_re_cli($id["id"], $cli["id"]);
				}
			}
		}			
		$this->logs[] = "FOUND clients:[".count($cli_list)."]";
		return $cli_list;
	}
	
	public function get_sms($letter, $comp)
	{
		$re_list = $this->load_re_list($comp, "sms");
		foreach($re_list as $re)
		{
			$count = 0;
			$find = "/".$re["re_find"]."/si";
			$repl = $re["re_repl"];
			
			// сначала ищем подстроку
			if(preg_match($find, $letter, $matches))
			{
				$s = $matches[0];
				$this->logs[] = "SMS SUBSTR: $s";
				$sms = preg_replace($find, $repl, $s, -1, $count);
				if($count == 0) continue;
				
				$msg = $this->db->escape($sms);
				$this->logs[] = "SMS: $msg";
				$this->save_re($re["id"], $sms);
				$this->save_sms($sms);
				return $sms;
			}
		}
		return false;
	}
	
	// ищем компанию по адресу в письме
	public function find_company($letter, $companies = null)
	{
		$this->save_msg($letter);
		if($companies == null) $companies = $this->load_companies();
		
		$email = $this->get_letter_sour_addr($letter);
		foreach($companies as $comp)
		{
			if(array_search($email, $comp['emails']) !== false)
			{
				$this->save_company($comp["id"]);
				$this->logs[] = "COMPANY title:[".$comp["title"]."] email [".$email."] from [".$comp["info"]."]";
				return $comp;
			}
		}
		return false;
	}
	*/
	
	public function parse_letter($letter)
	{
		// Сохраняем сообщение
		$msg_id = $this->save_msg($letter);
		
		// Ищем в письме email отправителя
		$email = $this->get_letter_sour_addr($letter);
		
		// Перебираем в цикле компании, чтобы найти такой email
		foreach($this->companies as $comp)
		{
			// Есть?
			if(array_search(strtoupper($email), $comp['emails']) !== false)
			{
				$this->update_company($msg_id, $comp['id']);
				
				// echo "company: ".$comp["title"]."\n";
				// Цикл по шаблонам
				foreach($comp['tpl'] as $tpl)
				{
					// echo $tpl['re_id']."\n";
					// Ищем ключевую последовательность в письме, как идентификатор клиента
					if(preg_match("/".$tpl['re_id']."/si", $letter, $matches))
					{
						// echo "\tRE id: ".$tpl['re_id']."\n";
						// Ищем клиента с таким идентификатором
						$cli = $this->find_client($matches[1], $comp);
						// нашли?
						if($cli)
						{
							// echo "\t\tCLI: ".$cli['ident']."\n";
							// Пытаемся сформировать для него SMS
							$sms_text = $this->make_sms($letter, $tpl);
							// echo "\t\t\tSMS: ".$sms_text."\n";
							if($sms_text)
							{
								$sms = array();
								// клиенту точно надо послать SMS?
								$sms['text'] = $sms_text;
								$sms['company_id'] = $comp['id'];
								$sms['cli'] = ($cli["enabled"] == 1) ? $cli : null;
								$sms['tpl'] = $tpl;
								// сохраняем в базе и возвращаем реультат
								$this->save_sms($msg_id, $sms);
								return $sms;
							}
						}
					}
				}
			}
		}
		// $this->logs[] = "FOUND identificators:[".count($id_list)."]";
		return false;
	}
	
	private function find_client($match, $comp)
	{
		$clients = $comp['cli'];
		foreach($clients as $cli)
			if($cli["ident"] == $match)
				return $cli;
			
		return false;
	}
	
	public function make_sms($letter, $tpl)
	{
		$find = "/".$tpl["re_find"]."/si";
		$repl = $tpl["re_repl"];
		
		// сначала ищем подстроку
		if(preg_match($find, $letter, $matches))
		{
			$s = $matches[0];
			$this->logs[] = "SMS SUBSTR: $s";
			$sms = preg_replace($find, $repl, $s, -1, $count);
			if($count == 0) return false;
			
			$msg = $this->db->escape($sms);
			$this->logs[] = "SMS: $msg";
			return $sms;
		}
		return false;
	}
	
	private function load_companies()
	{
		$sql = "SELECT id, dt, title, info FROM companies ORDER BY title";
		$rows = $this->load_assoc($sql);
		$companies = array();
		foreach($rows as $company)
		{
			$company['emails'] = $this->explode_emails(strtoupper($company['info']));
			$company['tpl'] = $this->load_templates($company);
			$company['cli'] = $this->load_clients($company);
			array_push($companies, $company);
		}
		return $companies;
	}
	
	private function load_templates($comp)
	{
		$sql = "SELECT id, title, re_id, re_find, re_repl, sms_it FROM templates WHERE company_id = ".$comp['id']." ORDER BY pos";
		return $this->load_assoc($sql);
	}

	public function load_clients($comp)
	{
		$sql = "SELECT id, dt, user_id, ident, phone, title, enabled, info FROM clients WHERE company_id = ".$comp['id'];
		return $this->load_assoc($sql);
	}
	
	private function load_assoc($sql)
	{
		$rows = array();
		$res = $this->db->query($sql);
		while($row = $this->db->fetch_assoc($res))
		{
			foreach($row as $key=>$val)
			{
				$row[$key] = $val;
			}
			array_push($rows, $row);
		}
		$this->db->free_result($res);
		return $rows;
	}
	
	private function save_msg($letter)
	{
		$letter = $this->db->escape($letter);
		$sql = "INSERT INTO msg(msg) VALUES($letter)";
		$this->db->query($sql);
		return $this->db->insert_id();
	}
	
	private function update_company($msg_id, $company_id)
	{
		$sql = "UPDATE msg SET company_id = $company_id WHERE id = $msg_id";
		$this->db->query($sql);
	}
	
	private function save_sms($msg_id, $sms)
	{
		$set_cli = "";
		if($sms['cli'])
			$set_cli = "client_id = ".$sms['cli']['id'].", ";
		
		$sql = "UPDATE msg SET ".$set_cli.
				"template_id = ".$sms['tpl']['id'].", sms = ".$this->db->escape($sms['text']).
				" WHERE id = ".$msg_id;
		$this->db->query($sql);
	}
	
	private function save_company($company_id)
	{
		$sql = "UPDATE msg SET company_id = $company_id WHERE id = ".$this->msg_id;
		$this->db->query($sql);
	}
	
	private function save_re($re_id, $re_res)
	{
		$res = $this->db->escape($re_res);
		$sql = "INSERT INTO msg_re_links(msg_id, re_id, re_res) VALUES(".$this->msg_id.", $re_id, $res)";
		$this->db->query($sql);
	}
	
	private function save_re_cli($re_id, $cli_id)
	{
		$sql = "INSERT INTO msg_cli_links(msg_id, re_id, cli_id) VALUES(".$this->msg_id.", $re_id, $cli_id)";
		$this->db->query($sql);
	}
	
	private function log2($type, $re_id, $comp_id, $cli_id, $msg, $as_parent)
	{
		$type_id = $this->log_types[$type];
		$pid = $this->db->escape($this->log_parent_id);
		$rid = $this->db->escape($re_id);
		$fid = $this->db->escape($comp_id);
		$cid = $this->db->escape($cli_id);
		$msg = $this->db->escape($msg);
		$sql = "INSERT INTO msg_log(type_id, parent_id, re_id, company_id, client_id, msg) ".
			"VALUES($type_id, $pid, $rid, $fid, $cid, $msg)";
		$this->db->query($sql);
		if($as_parent)
			$this->log_parent_id = $this->db->insert_id();
	}
	
	private function get_letter_sour_addr($letter)
	{
		// $pattern = '/from:?\s*(\S+)\s*\n/i';
		// $pattern = '/from\s*([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))\s/si';
		$pattern = '/\nfrom:\s*([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))\s/si';
		if(preg_match($pattern, $letter, $matches))
			return $matches[1];
		else
		{
			$pattern = '/\nfrom:[^<\n]*<([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))>\s/si';
			if(preg_match($pattern, $letter, $matches))
				return $matches[1];
			else
				return false;
		}
	}
	
	private function explode_emails($email_field)
	{
		// $email_field = str_replace(' ', ',', $email_field);
		$email_field = str_replace(', ', ',', $email_field);
		$email_field = str_replace(' ,', ',', $email_field);
		$email_field = str_replace(';', ',', $email_field);
		$email_field = str_replace(',,', ',', $email_field);
		$email_field = str_replace(',,', ',', $email_field);
		return explode(',', $email_field);
	}
}
